package com.sayice.robotconflict.view.page

import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp
import com.sayice.robotconflict.model.Message
import com.sayice.robotconflict.model.property.Direction
import com.sayice.robotconflict.model.receive.GameFrameData
import com.sayice.robotconflict.model.receive.GameRobotInfo
import com.sayice.robotconflict.model.send.MoveInfo
import com.sayice.robotconflict.ui.screen.*
import com.sayice.robotconflict.view.control.ControlButtons
import com.sayice.robotconflict.view.control.JoyStick
import com.sayice.robotconflict.view.control.TimeDisplay
import com.sayice.robotconflict.view.sprite.RobotSprite
import com.sayice.robotconflict.view.sprite.TowerSpirit
import com.sayice.robotconflict.viewmodel.GameViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.math.roundToInt

/**
 * 对局页面
 */
@Composable
fun Play(viewModel: GameViewModel) {
    val scope = rememberCoroutineScope()
    val gameFrameDataState by viewModel.gameFrameDataFlow.collectAsState(
        GameFrameData(0, emptyArray(), arrayOf(emptyArray(), emptyArray()))
    )
    val surrenderedCountState by viewModel.surrenderedCountFlow.collectAsState()
    var attacking by remember { mutableStateOf(false) }
    Box(
        modifier = Modifier
            .fillMaxSize()
            .wrapContentSize()
            .size(GAME_DESIGN_WIDTH.cdp, GAME_DESIGN_HEIGHT.cdp)
            .border(2.cdp, Color.Blue)
    ) {
        // 当前玩家携带的机器人
        val playerRobots = mutableListOf<GameRobotInfo>()
        // 当前玩家控制的机器人
        var controlledRobot: GameRobotInfo? = null
        // 对局时长显示
        TimeDisplay(
            millis = gameFrameDataState.gameTime,
            modifier = Modifier
                .align(Alignment.TopStart)
                .padding(horizontal = 5.cdp),
            color = Color.Blue, fontSize = 30.csp
        )
        // 能量塔
        for ((index, tower) in gameFrameDataState.towers.withIndex()) {
            TowerSpirit(
                coord = viewModel.towersCoord[index],
                tower = tower,
                isRival = index == 1,
                viewModel = viewModel
            )
        }
        // 己方机器人
        for (robot in gameFrameDataState.robots[viewModel.teamIndex]) {
            var bloodColor = Color.Blue
            var marked = false
            var onClick: (() -> Unit)? = null
            if (robot.playerId == viewModel.loginInfo.playerId) {
                playerRobots.add(robot)
                if (robot.controlled) {
                    controlledRobot = robot
                    marked = true
                }
                bloodColor = Color.Green
                onClick = {
                    scope.launch(Dispatchers.IO) {
                        viewModel.sendToServer(
                            Message(type = "game", action = "changeControl", data = robot.seq)
                        )
                    }
                }
            }
            RobotSprite(
                robot = robot,
                bloodColor = bloodColor,
                marked = marked,
                attacking = attacking,
                onClick = onClick,
                viewModel = viewModel
            )
        }
        // 敌方机器人
        for (robot in gameFrameDataState.robots[viewModel.rivalTeamIndex]) {
            RobotSprite(
                robot = robot,
                bloodColor = Color.Red,
                attacking = attacking,
                viewModel = viewModel
            )
        }
        // 投降按钮
        Row(
            modifier = Modifier
                .align(Alignment.TopEnd)
                .alpha(0.9f),
            verticalAlignment = Alignment.CenterVertically
        ) {
            repeat(surrenderedCountState) {
                Spacer(modifier = Modifier.width(3.cdp))
                Image(
                    painter = ColorPainter(Color.Green), contentDescription = "投降玩家数量标记",
                    modifier = Modifier.size(30.cdp)
                )
            }
            OutlinedButton(
                onClick = {
                    scope.launch(Dispatchers.IO) {
                        viewModel.sendToServer(Message(type = "game", action = "changeSurrender"))
                    }
                }, modifier = Modifier.defaultMinSize(1.dp, 1.dp),
                contentPadding = PaddingValues(horizontal = 10.cdp, vertical = 2.cdp)
            ) {
                Text(text = "投降", fontSize = 30.csp)
            }
        }
        // 机器人控制切换按钮组
        ControlButtons(
            modifier = Modifier.align(Alignment.CenterStart),
            elements = playerRobots,
            selected = controlledRobot,
            buttonSize = 100.cdp,
            space = 10.cdp,
            borderWidth = 10.cdp
        ) { current ->
            scope.launch(Dispatchers.IO) {
                viewModel.sendToServer(
                    Message(type = "game", action = "changeControl", data = current?.seq ?: -1)
                )
            }
        }
        // 摇杆
        JoyStick(modifier = Modifier.align(Alignment.BottomStart),
            size = 400.cdp,
            borderWidth = 2.cdp,
            onDragEnd = {
                scope.launch(Dispatchers.IO) {
                    viewModel.sendToServer(
                        Message(type = "game", action = "move", data = MoveInfo(speed = 0.0))
                    )
                }
            }
        ) { offset, length ->
            scope.launch(Dispatchers.IO) {
                val offsetX = offset.x.roundToInt()
                val offsetY = offset.y.roundToInt()
                viewModel.sendToServer(
                    Message(
                        type = "game",
                        action = "move",
                        data = MoveInfo(
                            direction = if (offsetX == 0 && offsetY == 0) null else Direction(
                                viewModel.directionOf(offsetX),
                                viewModel.directionOf(offsetY)
                            ),
                            speed = (length / 100.cpx).toDouble()
                        )
                    )
                )
            }
        }
        // 攻击按钮
        Image(
            painter = ColorPainter(Color.Blue), contentDescription = null,
            modifier = Modifier
                .align(Alignment.BottomEnd)
                .offset(y = (-100).cdp)
                .clip(CircleShape)
                .size(250.cdp)
                .alpha(0.3f)
                .pointerInput(Unit) {
                    detectTapGestures(
                        onPress = {
                            attacking = true
                            scope.launch(Dispatchers.IO) {
                                viewModel.sendToServer(Message(type = "game", action = "attack"))
                            }
                            tryAwaitRelease()
                            attacking = false
                        }
                    )
                }
        )
    }
}